﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using MoneyWentWhere.Utils;

namespace MoneyWentWhere.Utils.Storage
{
    /// <summary>
    /// File format to save documents in.
    /// </summary>
    /// <typeparam name="DocT"></typeparam>
    public abstract class FileFormat<DocT> : IDataFormat<DocT> 
        where DocT : class, IHasStorageInfo
    {
        /// <summary>
        /// Load the document from a file, with an optional password
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="password"></param>
        /// <throws>InvalidPasswordException</throws>
        /// <throws>InvalidDataException</throws>
        /// <throws>IOException</throws>
        /// <returns></returns>
        public virtual DocT Load(string filename, string password = null)
        {
            DocT doc;
            using (FileStream s = new FileStream(filename, FileMode.Open))
            {
                doc = Load(s, password);
            }

            // Save storage info
            doc.StorageInfo = new FileStorageInfo();
            doc.StorageInfo.Filename = filename;
            doc.StorageInfo.Password = password;
            doc.StorageInfo.DataFormat = this;

            IAfterLoad docAfterLoad = doc as IAfterLoad;
            if (docAfterLoad != null) { docAfterLoad.AfterLoad(); }

            return doc;
        }

        /// <summary>
        /// Save a document to a file. 
        /// Filename, password and format are taken from doc.StorageInfo object.
        /// </summary>
        /// <throws>IOException</throws>
        /// <param name="document"></param>
        public virtual void Save(DocT document)
        {
            document.ArgNotNull("document");
            document.StorageInfo.ArgNotNull("doc.StorageInfo");
            document.StorageInfo.Filename.ArgNotNullOrEmpty("doc.StorageInfo.Filename");

            using (FileStream s = new FileStream(document.StorageInfo.Filename, FileMode.Create))
            {
                Save(document, s);
            }
        }

        // override
        public virtual DocT Load(Stream inStream, string password = null)
        {
            throw new NotImplementedException();
        }

        // override
        public virtual void Save(DocT document, Stream outStream) 
        {
            throw new NotImplementedException();        
        }

    }
}
